<template>
  <div class="video-player-container">
    <!-- controls -->
    <video
      ref="videoPlayer"
      class="video-js vjs-default-skin"
      style="padding-top: 0;"
      muted autoplay
      preload="auto"
      :width="width"
      :height="height"
      data-setup="{}"
    >
      <source :src="processedSrc" :type="sourceType" />
      <p class="vjs-no-js">
        To view this video please enable JavaScript, and consider upgrading to a
        web browser that
        <a href="https://videojs.com/html5-video-support/" target="_blank"
          >supports HTML5 video</a
        >
      </p>
    </video>
    <!-- <div v-if="errorMessage" class="error-message">
      <p>❌ {{ errorMessage }}</p>
      <button @click="initPlayer" class="retry-btn">重试</button>
    </div> -->
    <!-- RTSP转换提示 -->
    <div v-if="isRTSP && !isConverted" class="rtsp-notice">
      <div class="loading-tip">
        <span class="loading-spinner"></span>
        正在转码RTSP流，请稍候...
      </div>
    </div>

    <!-- 错误提示 -->
    <div v-if="errorMessage" class="error-message">
      <div class="error-alert">
        <span class="error-icon">⚠️</span>
        <span class="error-text">{{ errorMessage }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue";
import videojs from "video.js";
import "video.js/dist/video-js.css";
import Hls from "hls.js";

const props = defineProps({
  src: {
    type: String,
    required: true,
  },
  width: {
    type: [String, Number],
    default: 640,
  },
  height: {
    type: [String, Number],
    default: 360,
  },
  autoplay: {
    type: Boolean,
    default: false,
  },
  muted: {
    type: Boolean,
    default: false,
  },
  loop: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(["ready", "error", "rtsp-convert"]);

const videoPlayer = ref(null);
const player = ref(null);
const isConverted = ref(false);
const errorMessage = ref("");

// 判断是否为RTSP流
const isRTSP = computed(() => {
  return props.src && props.src.startsWith("rtsp://");
});

// 处理后的视频源
const processedSrc = computed(() => {
  if (isRTSP.value) {
    // 如果是RTSP，返回转换后的HLS地址
    return convertRTSPToHLS(props.src);
  }
  return props.src;
});

// 视频源类型
const sourceType = computed(() => {
  if (processedSrc.value.includes(".m3u8")) {
    return "application/x-mpegURL";
  } else if (processedSrc.value.includes(".mp4")) {
    return "video/mp4";
  } else if (processedSrc.value.includes(".webm")) {
    return "video/webm";
  }
  return "video/mp4";
});

// RTSP转HLS转换函数
const convertRTSPToHLS = (rtspUrl) => {
  console.log("转换RTSP到HLS:", rtspUrl);

  // 模拟转码过程
  setTimeout(() => {
    isConverted.value = true;
    emit("rtsp-convert", {
      rtsp: rtspUrl,
      hls:
        rtspUrl
          .replace("rtsp://", "http://")
          .replace(/:554\//, ":8080/hls/")
          .replace(/openUrl\//, "") + ".m3u8",
    });
  }, 1000);

  // 返回模拟的HLS地址
  return (
    rtspUrl
      .replace("rtsp://", "http://")
      .replace(/:554\//, ":8080/hls/")
      .replace(/openUrl\//, "") + ".m3u8"
  );
};

// 初始化播放器
const initPlayer = () => {
  if (!videoPlayer.value) return;

  try {
    const options = {
      autoplay: props.autoplay,
      controls: true,
      responsive: true,
      fluid: true,
      muted: props.muted,
      loop: props.loop,
      sources: [
        {
          src: processedSrc.value,
          type: sourceType.value,
        },
      ],
      techOrder: ["html5"],
      html5: {
        hls: {
          enableLowInitialPlaylist: true,
          smoothQualityChange: true,
          overrideNative: true,
        },
      },
    };

    // 创建播放器实例
    player.value = videojs(videoPlayer.value, options, () => {
      console.log("Video.js player is ready");
      emit("ready", player.value);
    });

    // 监听错误事件
    player.value.on("error", (error) => {
      console.error("Video.js error:", error);
      handleError(error);
    });
  } catch (error) {
    console.error("初始化播放器失败:", error);
    handleError(error);
  }
};

// 错误处理
const handleError = (error) => {
  console.error("视频播放错误:", error);

  let message = "视频加载失败";
  if (error && error.code === 4) {
    message = "视频源不可用，请检查网络连接";
  } else if (error && error.code === 2) {
    message = "视频格式不支持";
  } else if (isRTSP.value) {
    message = "RTSP流需要后端转码服务支持";
  }

  errorMessage.value = message;
  emit("error", error);
};

// 监听src变化
watch(
  () => props.src,
  (newSrc) => {
    if (player.value && newSrc) {
      player.value.src({
        src: processedSrc.value,
        type: sourceType.value,
      });
    }
  }
);

onMounted(() => {
  // 确保DOM加载完成
  nextTick(() => {
    initPlayer();
  });
});

onUnmounted(() => {
  if (player.value) {
    player.value.dispose();
    player.value = null;
  }
});

// 暴露方法给父组件
const play = () => {
  if (player.value) {
    player.value.play();
  }
};

const pause = () => {
  if (player.value) {
    player.value.pause();
  }
};

const seek = (time) => {
  if (player.value) {
    player.value.currentTime(time);
  }
};

const getPlayer = () => {
  return player.value;
};

defineExpose({
  play,
  pause,
  seek,
  getPlayer,
});
</script>

<style scoped>
.vjs_video_3-dimensions.vjs-fluid:not(.vjs-audio-only-mode) {
  padding-top: 0!important;
}
/* 在 VideoPlayer 组件样式中添加 */
:deep(.video-js) {
  width: 100%!important;
  height: 100%!important;
}

:deep(.vjs-tech) {
  object-fit: cover;
  width: 100%;
  height: 100%;
}

/* 添加视频容器样式确保充满 */
.video-player-container {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 100%;
  height: 100%;
}

/* 确保 video 元素充满容器 */
:deep(video) {
  object-fit: cover !important;
  width: 100% !important;
  height: 100% !important;
}
.video-player-container {
  display: flex;
  align-items: center;
  position: relative;
  width: 100%;
  height: 100%;
}

.rtsp-notice {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 10;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 20px;
  border-radius: 8px;
  text-align: center;
}

.loading-tip {
  display: flex;
  align-items: center;
  gap: 10px;
}

.loading-spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid #ffffff;
  border-radius: 50%;
  border-top-color: transparent;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.error-message {
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  z-index: 10;
}

.error-alert {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  background: #fef0f0;
  border: 1px solid #fde2e2;
  border-radius: 4px;
  color: #f56c6c;
}

:deep(.video-js) {
  width: 100%;
  height: 100%;
}

:deep(.vjs-tech) {
  object-fit: cover;
}
</style>